package executor;

import mapper.SqlCommandType;
import support.JDBCUtil;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;


public class DefaultExecutor implements Executor {

    static {
        System.out.println("DefaultExecutor is loaded");
    }


    private ParameterHandler parameterHandler = new DefaultParameterHandler();
    private StatementHandler statementHandler = new DefaultStatementHandler();

    /**
     * 执行除select以外的，其他三种查询
     *
     * @param sqlType
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     */
    public Object execute(SqlCommandType sqlType, String sql, Object[] params) throws SQLException {
        Object result = null;
        switch (sqlType) {
            case DELETE:
                result = executeDelete(sql, params);
                break;
            case INSERT:
                result = executeInsert(sql, params);
                break;
            case UPDATE:
                result = executeUpdate(sql, params);
                break;
            case UNKNOWN:
                throw new RuntimeException("语句必须是 select，insert,update,delete");
        }
        return result;
    }

    public <T> List<T> executeSelect(String sql, Object[] params, Class<T> tClass) throws SQLException {
        PreparedStatement preparedStatement = dopreparedstatement(sql, params);
        return doExecuteSelect(preparedStatement, tClass);
    }

    public <T> T executeSelectOne(String sql, Object[] params, Class<T> tClass) throws SQLException {
        List<T> list = executeSelect(sql, params, tClass);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    private <T> List<T> doExecuteSelect(PreparedStatement preparedStatement, Class<T> tClass) {
        try {
            return JDBCUtil.getListCommBean(preparedStatement, tClass);
        } catch (InstantiationException | IllegalAccessException | SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

    private int executeUpdate(String sql, Object[] params) throws SQLException {

        PreparedStatement preparedStatement = dopreparedstatement(sql, params);
        return doExecuteUpdate(preparedStatement);
    }

    private int doExecuteUpdate(PreparedStatement preparedStatement) throws SQLException {
        return JDBCUtil.updateRecord(preparedStatement);

    }

    private int executeDelete(String sql, Object[] params) throws SQLException {
        return executeUpdate(sql, params);
    }

    private int executeInsert(String sql, Object[] params) throws SQLException {
        return executeUpdate(sql, params);
    }


    /**
     * PreparedStatement
     *
     * @return 返回已经准备好的 PreparedStatement
     */
    private PreparedStatement dopreparedstatement(String sql, Object[] params) throws SQLException {
        //获取statement
        PreparedStatement statement = statementHandler.getStatement(sql);
        //设置参数
        statement = parameterHandler.setSqlParameter(statement, params);
        return statement;
    }


    public void setParameterHandler(ParameterHandler parameterHandler) {
        this.parameterHandler = parameterHandler;
    }

    public void setStatementHandler(StatementHandler statementHandler) {
        this.statementHandler = statementHandler;
    }
}
